package com.kfyang.manualgear.util;

import com.kfyang.manualgear.generator.declare.ClassSpecGenerator;
import com.kfyang.manualgear.generator.declare.ClassWrapper;
import com.kfyang.manualgear.generator.declare.ModifyMethodGenerator;
import com.kfyang.manualgear.generator.declare.QueryMethodGenerator;
import com.kfyang.manualgear.generator.declare.orm.OrmGenerator;
import com.kfyang.manualgear.generator.impl.hibernate.ClassSpecGeneratorHibernateImpl;
import com.kfyang.manualgear.generator.impl.hibernate.ModifyMethodGeneratorHibernateImpl;
import com.kfyang.manualgear.generator.impl.hibernate.QueryMethodGeneratorHibernateImpl;
import com.kfyang.manualgear.generator.impl.hibernate.orm.OrmGeneratorHibernateImpl;
import com.kfyang.manualgear.generator.impl.jdbc.ClassSpecGeneratorJdbcImpl;
import com.kfyang.manualgear.generator.impl.jdbc.ModifyMethodGeneratorJdbcImpl;
import com.kfyang.manualgear.generator.impl.jdbc.QueryMethodGeneratorJdbcImpl;
import com.kfyang.manualgear.generator.impl.jdbc.orm.OrmGeneratorJdbcImpl;

import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.type.TypeMirror;
import java.util.List;

public enum Engine {
    JDBC, HIBERNATE;

    public ClassSpecGenerator getClassSpecGenerator(Element element) {
        return switch (this) {
            case JDBC -> new ClassSpecGeneratorJdbcImpl(element);
            case HIBERNATE -> new ClassSpecGeneratorHibernateImpl(element);
        };
    }

    public OrmGenerator getOrmGenerator(List<ExecutableElement> elements, TypeMirror entityType) {
        return switch (this) {
            case JDBC -> new OrmGeneratorJdbcImpl(elements, entityType);
            case HIBERNATE -> new OrmGeneratorHibernateImpl(elements, entityType);
        };
    }

    public QueryMethodGenerator getQueryMethodGenerator(ExecutableElement methodElement, ClassWrapper classWrapper, boolean useSimple) {
        return switch (this) {
            case JDBC -> new QueryMethodGeneratorJdbcImpl(methodElement, classWrapper, useSimple);
            case HIBERNATE -> new QueryMethodGeneratorHibernateImpl(methodElement, classWrapper, useSimple);
        };
    }

    public ModifyMethodGenerator getModifyMethodGenerator(ExecutableElement methodElement, ClassWrapper classWrapper, boolean useSimple) {
        return switch (this) {
            case JDBC -> new ModifyMethodGeneratorJdbcImpl(methodElement, classWrapper, useSimple);
            case HIBERNATE -> new ModifyMethodGeneratorHibernateImpl(methodElement, classWrapper, useSimple);
        };
    }
}
